package org.dfzt.common.util;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.stereotype.Component;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Set;

@Component
public class VerifyParam {
    private static final Log log = LogFactory.getLog(VerifyParam.class);
    private static JSONObject verifyParamsJson=new JSONObject();
    static {
        InputStream is = null;
        StringBuffer res = new StringBuffer();
        InputStreamReader isr = null;
        BufferedReader read = null;
        try {
            is=VerifyParam.class.getClassLoader().getResourceAsStream("static/verifyParam.json");
            if(is!=null){
                isr = new InputStreamReader(is);
                read = new BufferedReader(isr);
                String line;
                while ((line = read.readLine())!= null) {
                    res.append(line);
                }
                verifyParamsJson=JSON.parseObject(res.toString());
            }
        } catch (IOException ignored) {
        } finally {
            try {
                if (null != isr) {
                    isr.close();
                }
                if (null != read) {
                    read.close();
                }
                if (null != is) {
                    is.close();
                }
            } catch (IOException ignored) {
            }
        }
    }


    public static boolean verifyString(String str,int minLen,int maxLen){
        boolean flag=false;
        if(oConvertUtils.isEmpty(str)){
            str="";
        }
        if(str.trim().length()>=minLen&&str.trim().length()<=maxLen){
            flag=true;
        }
        return flag;
    }

    public static boolean verifyNum(String num,int min,int max){
        boolean flag=false;
        if(StringUtils.isNotEmpty(num)){
            try {
                int i = Integer.parseInt(num);
                flag =verifyNum(i,min,max);
            } catch (NumberFormatException e) {
                flag=false;
            }
        }
        return flag;
    }
    public static boolean verifyNum(Integer num,int min,int max){
        boolean flag=false;
        if(num==null){
            num=0;
        }
        if(num>=min&&num<=max){
            flag=true;
        }
        return flag;
    }

    public static boolean verifyNum(double num,double min,double max){
        boolean flag=false;
        if(num>=min&&num<=max){
            flag=true;
        }
        return flag;
    }

    public static boolean verifyNum(String num,double min,double max){
        boolean flag=false;
        if(StringUtils.isNotEmpty(num)){
            try {
                double i = Double.parseDouble(num);
                flag =verifyNum(i,min,max);
            } catch (NumberFormatException e) {
                flag=false;
            }
        }
        return flag;
    }

    public static boolean verifyDate(String dateStr){
        boolean flag=true;
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        SimpleDateFormat format2 = new SimpleDateFormat("yyyy-MM-dd");
        try {
            format.parse(dateStr);
        } catch (Exception e) {
            try {
                format2.parse(dateStr);
            } catch (ParseException e1) {
                flag = false;
            }
        }
        return flag;
    }


    /**
     * 验证数据类型
     * paramValue为对象时   paramName为对象的类名 type为object
     * paramValue为基本数据类型时   paramName为属性名 type为null或对象类名（为对象名的话将以对象类名.属性名检索）
     * */
    public static boolean verifyParam(String paramName,Object paramValue,String type){
        boolean flag=false;
        if(paramValue!=null){
            String str=JSON.toJSONString(paramValue);
            if("object".equalsIgnoreCase(type)){//如果为对象的话  需要逐一验证
                JSONObject jb = JSON.parseObject(str);
                Set<String> strings = jb.keySet();
                if(strings.size()==0){
                    return true;
                }
                for(String sss:strings){
                    flag=verifyParamInJson(paramName,sss,jb.getString(sss));
                    if(!flag){
                        return false;
                    }
                }
            }else{
                flag=verifyParamInJson(type,paramName,paramValue);
            }
        }
        return flag;
    }

    /**
     * 验证json中有的基本类型的参数
     * */
    public static boolean verifyParam(String paramName,Object paramValue){
        return verifyParam(paramName,paramValue,null);
    }

    public static boolean verifyParamInJson(String className,String paramName,Object paramValue){
        boolean flag=false;
        String str=paramValue+"";
        JSONObject temp;
        if(className==null){//如果不传类名  则直接用参数名搜索
            temp = verifyParamsJson.getJSONObject(paramName);
        }else{//如果有的话  则以.拼接后搜索
            temp=verifyParamsJson.getJSONObject(className+"."+paramName);
            if(temp==null){//如果还为null  则以参数名搜索
                temp=verifyParamsJson.getJSONObject(paramName);
            }
        }
        if(temp!=null){
            int maxI = temp.getIntValue("max");
            int minI = temp.getIntValue("min");
            String type = temp.getString("type");
            switch (type){
                case "int":
                    flag=verifyNum(str,minI,maxI);
                    break;
                case "date":
                    flag=verifyString(str,11,25);
                    break;
                case "string":
                    flag=verifyString(str,minI,maxI);
                    break;
                case "boolean":
                    flag= "true".equalsIgnoreCase(str) || "false".equalsIgnoreCase(str);
                    break;
                case "double":
                    double maxD = temp.getDoubleValue("max");
                    double minD = temp.getDoubleValue("min");
                    flag=verifyNum(str,minD,maxD);
                    break;
                default:
                    flag = false;
                    break;
            }
        }

        if(!flag){
            log.info(className+"."+paramName+":"+paramValue+"<----验证不通过");
        }
        return flag;
    }


}
